package com.rq.base.ui;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.SparseArray;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;


import com.rq.base.R;
import com.rq.base.ui.common.CommonFragment;
import com.rq.base.ui.img_load.ImageLoadUtil;
import com.rq.base.ui.impl.OnClick;
import com.rq.base.ui.impl.ViewParam;
import com.rq.base.util.GsonUtil;
import com.rq.base.util.LOG;
import com.rq.rvlibrary.BaseAdapter;
import com.rq.rvlibrary.BaseViewHolder;
import com.rq.rvlibrary.RecyclerUtil;

//import org.angmarch.views.DefaultShow;
//import org.angmarch.views.NiceSpinner;
//import org.angmarch.views.OnSpinnerItemSelectedListener;
//import org.json.JSONException;
//import org.json.JSONObject;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.recyclerview.widget.RecyclerView;

/**
 * @author RQ
 * date    2022-01-27 15:39
 */
public class ViewDelegate {
    private static Handler mainHandler = new Handler(Looper.getMainLooper());
    private FillMoreMethod mMoreMethod;
    private View.OnClickListener mClickListener;
    private OnViewCreate mOnViewCreate;
    private Object passObj, viewRoot;
    private Context mContext;
    /**
     * 页面子控件
     */
    private SparseArray<View> viewSparseArray = new SparseArray<>();

    public ViewDelegate() {
        LOG.e("ViewDelegate", "ViewDelegate.51:");//####  1
    }

    public void setContext(Context context) {
        this.mContext = context;
    }

    public void setViewRoot(Object context) {
        this.viewRoot = context;
    }

    public void initController(Object obj) {
        if (obj == null) {
            return;
        }
        this.passObj = obj;
        if (obj instanceof FillMoreMethod) {
            this.mMoreMethod = (FillMoreMethod) obj;
        }
        if (obj instanceof OnViewCreate) {
            this.mOnViewCreate = (OnViewCreate) obj;
        }
        if (obj instanceof View.OnClickListener) {
            this.mClickListener = (View.OnClickListener) obj;
        }
    }

    private Context getContext() {
        return mContext;
    }

    public <T extends View> T getView(int id) {
        View finView = this.viewSparseArray.get(id);
        if (finView != null) {
            return (T) finView;
        }
        if (this.viewRoot != null) {
            if (this.viewRoot instanceof Activity) {
                finView = ((Activity) this.viewRoot).findViewById(id);
            } else if (this.viewRoot instanceof Fragment) {
                if (((Fragment) this.viewRoot).getView() != null) {
                    finView = ((Fragment) this.viewRoot).getView().findViewById(id);
                }
            } else if (this.viewRoot instanceof BaseViewHolder) {
                finView = ((BaseViewHolder) this.viewRoot).itemView.findViewById(id);
            } else if (this.viewRoot instanceof View) {
                finView = ((View) this.viewRoot).findViewById(id);
            }
            if (finView != null) {
                viewSparseArray.put(id, finView);
            }
        }
        return (T) finView;
    }

    private static final boolean isArray(Object obj) {
        if (obj == null) {
            return false;
        }
        return obj.getClass().isArray();

    }

    public void setData2View(final int viewId, final Object obj) {
        if (isArray(obj)) {
            Object[] con = (Object[]) obj;
            for (Object o : con) {
                setData2View(viewId, o);
            }
            return;
        }
        if (Looper.myLooper() == Looper.getMainLooper()) {//主线程
            setDataToView(viewId, obj);
        } else {
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    setDataToView(viewId, obj);
                }
            });
        }
    }

    public void setData2ViewParent(final int viewId, final Object obj) {
        View view = getView(viewId);
        if (view != null) {
            final View vp = (View) view.getParent();
            if (vp != null) {
                if (Looper.myLooper() == Looper.getMainLooper()) {//主线程
                    setDataToView(vp, obj);
                } else {
                    mainHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            setDataToView(vp, obj);
                        }
                    });
                }
            }
        }

    }

    private void setDataToView(int viewId, Object object) {
        if (viewSparseArray.get(viewId) != null) {
            setDataToView(viewSparseArray.get(viewId), object);
        } else {
            View v = getView(viewId);
            if (v != null) {
                if (viewSparseArray.indexOfValue(v) < 0) {
                    viewSparseArray.append(viewId, v);
                }
                setDataToView(v, object);
            }
        }
    }

    public synchronized void setSpinnerView(View v, Object obj) {
//        if (obj instanceof List) {
//            ((NiceSpinner) v).attachDataSource((List) obj);
//            LOG.e("FangYuanController", "setData2View.257:");
//        } else if (obj instanceof OnSpinnerItemSelectedListener) {
//            LOG.e("FangYuanController", "setData2View.259:");
//            ((NiceSpinner) v).setOnSpinnerItemSelectedListener((OnSpinnerItemSelectedListener) obj);
//        } else if (obj instanceof DefaultShow) {
//            ((NiceSpinner) v).setDefaultShow((DefaultShow) obj);
//        }
    }


    final synchronized void setDataToView(View view, Object obj) {
        if (view == null) {
            LOG.utilLog("ViewEmpty");
            return;
        }
        if (mMoreMethod != null && mMoreMethod.fillCustomViewData(view, obj)) {
            return;
        }
        if (obj instanceof Integer && ((int) obj == View.VISIBLE || (int) obj == View.GONE || (int) obj == View.INVISIBLE)) {
            view.setVisibility((int) obj);
            return;
        }
        //    if (obj == null) {
        //      LOG.utilLog("DataEmpty hide");
        //      view.setVisibility(View.GONE);
        //      return;
        //    }

//        if (view instanceof NiceSpinner) {
//            setSpinnerView(view, obj);
//            return;
//        }
        if (obj instanceof ViewParam) {
            if (obj == ViewParam.ENABLE) {
                view.setEnabled(true);
            } else if (obj == ViewParam.UNABLE) {
                view.setEnabled(false);
            } else if (obj == ViewParam.CHECKABLE) {
                view.setClickable(true);
            } else if (obj == ViewParam.UNCHECKABLE) {
                view.setClickable(false);
            } else if (obj == ViewParam.SELECTED) {
                view.setSelected(true);
            } else if (obj == ViewParam.UNSELECTED) {
                view.setSelected(false);
            }
            return;
        }
        if (obj instanceof View.OnClickListener) {
            view.setOnClickListener((View.OnClickListener) obj);
            return;
        }
        //    if (obj instanceof OnRefuseAndLoadListener.Status && view instanceof SmartRefreshLayout) {
        //      if (obj == FinishRefuseAndLoad) {
        //        ((SmartRefreshLayout) view).finishLoadMore();
        //        ((SmartRefreshLayout) view).finishRefresh();
        //      } else if (obj == OnRefuseAndLoadListener.Status.FinishLoad) {
        //        ((SmartRefreshLayout) view).finishLoadMore();
        //      } else if (obj == OnRefuseAndLoadListener.Status.FinishRefuse) {
        //        ((SmartRefreshLayout) view).finishRefresh();
        //      } else if (obj == OnRefuseAndLoadListener.Status.loadAble_False) {
        //        ((SmartRefreshLayout) view).setEnableLoadMore(false);
        //      } else if (obj == OnRefuseAndLoadListener.Status.loadable_True) {
        //        ((SmartRefreshLayout) view).setEnableLoadMore(true);
        //      } else if (obj == OnRefuseAndLoadListener.Status.refreshable_False) {
        //        ((SmartRefreshLayout) view).setEnableRefresh(false);
        //      } else if (obj == OnRefuseAndLoadListener.Status.refreshable_True) {
        //        ((SmartRefreshLayout) view).setEnableRefresh(true);
        //      }
        //      return;
        //    }
        if (obj instanceof Boolean) {
            if (view instanceof CompoundButton) {
                ((CompoundButton) view).setChecked((boolean) obj);
            } else {
                view.setSelected((boolean) obj);
            }
            return;
        }
        if (view instanceof ImageView) {
            fillImageView((ImageView) view, obj);
        } else if (view instanceof TextView) {
            fillTextView((TextView) view, obj);
        } else if (view instanceof RecyclerView) {
            LOG.d("ViewDelegate", "setDataToView.833:");
            view.setOverScrollMode(View.OVER_SCROLL_NEVER);
            fillRecyclerViewData((RecyclerView) view, obj);
        } else if (view instanceof FrameLayout) {
            fillFrameLayout((FrameLayout) view, obj);
        }
    }

    protected void fillImageView(ImageView view, Object obj) {
        if (obj == null) return;
        LOG.d("ViewDelegate", (obj instanceof Drawable) + ".1126:" + obj.getClass());
        if (obj instanceof Bitmap) {
            view.setImageBitmap((Bitmap) obj);
        } else if (obj instanceof Integer) {
            view.setImageResource((int) obj);
        } else if (obj instanceof Drawable) {
            view.setImageDrawable((Drawable) obj);
        } else if (obj instanceof String) {
            String con = (String) obj;
            if (con.startsWith("#")) {
                view.setBackgroundColor(Color.parseColor(con));
            } else if (con.startsWith("http")) {
                try {
                    URL url = new URL(con);
                    ImageLoadUtil.display(getContext(), url, view);
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                }
            } else {
                LOG.d("ViewDelegate", "fillImageView.未知图片:" + con);
            }

        } else if (obj instanceof URL) {
            ImageLoadUtil.display(getContext(), obj, view);
        } else {
            LOG.d("ViewDelegate", "fillImageView.异常资源:" + obj.getClass().getSimpleName() + ":" + obj);
        }
    }

    protected void fillTextView(TextView view, Object obj) {
        if (obj == null) {
            view.setText("");
        } else if (obj instanceof CharSequence) {
            view.setText((CharSequence) obj);
        } else if (obj instanceof Integer) {
            view.setText((int) obj);
        } else {
            view.setText(String.valueOf(obj));
        }
    }

    FragmentManager mFragmentManager;

    protected void fillFrameLayout(FrameLayout view, Object obj) {
        if (mFragmentManager == null) {
            if (viewRoot instanceof FragmentActivity) {
                mFragmentManager = ((FragmentActivity) viewRoot).getSupportFragmentManager();
            } else if (viewRoot instanceof Fragment) {
                mFragmentManager = ((Fragment) viewRoot).getFragmentManager();
            } else {
                LOG.e("ViewDelegate", "fillFrameLayout.265:");
                return;
            }
        }
        LOG.e("ViewDelegate", "fillFrameLayout.269:");
        FragmentTransaction mFragmentTransaction = mFragmentManager.beginTransaction();
        BaseFragment fragment = null;
        if (obj instanceof Class) {
            fragment = CommonFragment.instance((Class<BaseController>) obj);
        } else if (obj instanceof BaseFragment) {
            fragment = (BaseFragment) obj;
        } else if (obj instanceof FragmentContainer) {
            fragment = ((FragmentContainer) obj).getLastFra();
            fragment.getController().setOperator(((FragmentContainer) obj));
        }
        if (fragment == null) {
            LOG.d("BaseController", "fillFrameLayout.fragment == null");
            return;
        }
        FragmentTransaction ft = mFragmentTransaction;
        LOG.d("BaseController", "fillFrameLayout.fragment.getStrTag():" + fragment.getStrTag());
        Fragment showFg = null;
        String tagPage = null;
        Fragment show = null;
        for (Fragment item : mFragmentManager.getFragments()) {
            if (!item.isHidden()) {
                show = item;
            }
        }
        try {
            tagPage = (String) view.getTag(R.id.tag_key);
            showFg = mFragmentManager.findFragmentByTag(tagPage);
        } catch (Exception e) {
        }
        if (!fragment.isAdded() && null == mFragmentManager.findFragmentByTag(tagPage)) {
            if (showFg != null) {
                ft.hide(showFg).add(view.getId(), fragment, tagPage);
            } else {
                view.setTag(R.id.tag_key, tagPage);
                ft.add(view.getId(), fragment, tagPage);
            }
        } else { //已经加载进容器里去了....
            if (show != null) {
                ft.hide(show).show(fragment);
            } else {
                ft.show(fragment);
            }
        }
        if (viewRoot instanceof FragmentActivity) {
            if (((FragmentActivity) viewRoot).isFinishing()) {
                return;
            }
        } else if (viewRoot instanceof Fragment) {
            if (((Fragment) viewRoot).getActivity().isFinishing()) {
                return;
            }
        }
        ft.commitAllowingStateLoss();
        mFragmentManager.executePendingTransactions();
    }

    protected void fillRecyclerViewData(RecyclerView recyclerView, Object obj) {
        if (obj instanceof RecyclerUtil) {
            ((RecyclerUtil) obj).set2View(recyclerView);
        } else if (obj instanceof BaseAdapter) {
            new RecyclerUtil((BaseAdapter) obj).set2View(recyclerView);
        } else if (obj instanceof RecyclerView.Adapter) {
            new RecyclerUtil((RecyclerView.Adapter) obj).set2View(recyclerView);
        } else if (obj instanceof RecyclerView.LayoutManager) {
            recyclerView.setLayoutManager((RecyclerView.LayoutManager) obj);
        } else if (obj instanceof RecyclerView.ItemDecoration) {
            recyclerView.addItemDecoration((RecyclerView.ItemDecoration) obj);
        }
    }

    public void onViewCreate(@Nullable Bundle savedInstanceState) {
        LOG.e("ViewDelegate", "onViewCreate.360:");
        if (this.mClickListener != null) {
            initClick();
        }
    }

    private void initClick() {
        if (isImplements(View.OnClickListener.class)) {
            LOG.e("ViewDelegate", "onViewCreate.362:");
            Method method = null;
            try {
                method = get(View.OnClickListener.class).getClass()
                        .getDeclaredMethod("onClick", View.class);
            } catch (NoSuchMethodException e) {
                LOG.d("ViewDelegate", "onViewCreated.570:" + e.getMessage());
            }
            if (method == null) {
                LOG.e("ViewDelegate", "onViewCreate.370:");
                return;
            }
            Annotation[] annotations = method.getAnnotations();
            if (annotations.length > 0) {
                for (Annotation annotation : annotations) {
                    if (annotation instanceof OnClick) {
                        OnClick inject = (OnClick) annotation;
                        LOG.e("ViewDelegate", "setOnClickListener:");
                        int[] value = inject.value();
                        for (int id : value) {
                            setData2View(id, this.mClickListener);
                        }
                    }
                }
            }
        }
    }

    public <T> T get(Class<T> type) {
        return type.cast(this.passObj);
    }

    protected final boolean isImplements(Class<?> clazz) {
        boolean res = clazz.isAssignableFrom(this.passObj.getClass());
        return res;
    }

    public int layoutId() {
        if (mOnViewCreate != null) {
            return mOnViewCreate.getLayoutId();
        }
        return 0;
    }

    public void setViewTag(final int viewId, final Object tag) {
        final View view = getView(viewId);
        if (view != null) {
            if (Looper.myLooper() == Looper.getMainLooper()) {//主线程
                view.setTag(tag);
            } else {
                mainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        view.setTag(tag);
                    }
                });
            }
        }
    }

    public Object getViewTag(int viewId) {
        final View view = getView(viewId);
        if (view != null) {
            return view.getTag();
        }
        return null;
    }

    public String getInput(int viewId, int sub) {
        try {
            String in = ((TextView) getView(viewId)).getText().toString().trim();
            return in.substring(sub);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    protected String getSpinner(int vId, String... value) {
//        NiceSpinner v = getView(vId);
//        if (v == null) return "";
//        Object select = null;
//        try {
//            select = v.getSelectedItem();
//        } catch (Exception e) {
//        }
//        if (select == null) {
//            return "";
//        }
//        if (select instanceof String) {
//            return (String) select;
//        }
//        try {
//            JSONObject j = new JSONObject(GsonUtil.getString(select));
//            return (String) j.get("dictValue");
//        } catch (JSONException e) {
//        }
//        if (value != null && value.length > 0) {
//            try {
//                JSONObject j = new JSONObject(GsonUtil.getString(select));
//                return (String) j.get(value[0]);
//            } catch (JSONException e) {
//            }
//            return value[value.length - 1];
//        }
        return "";
    }
}
